#include "../utility/assert_helper.h"
#include "../utility/file_helper.h"
#include "windows_information.h"

const char	* OLD_SYSTEM_DIRECTORY = "system";
const char	* NEW_SYSTEM_DIRECTORY = "system32";
const char	* OLD_TEMP_DIRECTORY = "temp";
const char	* USERS_HOME_DIRECTORY = "Documents and Settings";

Windows_Information::Windows_Information(const char * win_root, Windows_Edition ver) :
version_(ver)
{
	IF_NULL_RETURN(win_root);
	user_count_ = 0;
	set_windows_root_directory(win_root);
}

Windows_Information::~Windows_Information()
{
	//if (NULL != win_dir_) delete [] win_dir_;
}

int
Windows_Information::set_directories(const char * path, Path_Token token)
{
	IF_NULL_RETURN_VALUE(path, -1);

	if (SET_PATH_FROM_WINDOWS_DIR == token) {
		directories_[WINDOWS_DIR] = path;
		if ('/' == directories_[WINDOWS_DIR].at(directories_[WINDOWS_DIR].length() - 1)) { 
			// 暂且不应该以 / 结尾
			return -1;
		}
		directories_[SYSTEM_DIR] += directories_[WINDOWS_DIR] + "/" +
		((version_ > WINDOWS_95 && version_ <= WINDOWS_VISTA) ? NEW_SYSTEM_DIRECTORY : OLD_SYSTEM_DIRECTORY);
		directories_[WINDOWS_TEMP] += directories_[WINDOWS_DIR] + "/" + OLD_TEMP_DIRECTORY;

		directories_[WINDOWS_ROOT] = directories_[WINDOWS_DIR].substr(0, directories_[WINDOWS_DIR].rfind("/"));
		directories_[HOME_DIR] = directories_[WINDOWS_ROOT] + "/" + USERS_HOME_DIRECTORY;
	} else {
		directories_[token] = path;
	}

	return 0;
}

const char *
Windows_Information::get_directorie(Path_Token token) const
{
	// TODO: we will check token range
	return directories_[token].c_str();
}

Windows_Edition
Windows_Information::get_windows_version() const
{
	return version_;
}

Windows_Information_Collection::Windows_Information_Collection()
{
}

Windows_Information_Collection::~Windows_Information_Collection()
{
	clear_all_information();
}

void	
Windows_Information_Collection::clear_all_information()
{
	Windows_Info_Collection::iterator end = windows_info_collection_.end();
	for (Windows_Info_Collection::iterator index; end != index; ++index) {
		delete *index;
	}
	windows_info_collection_.clear();
}

int	
Windows_Information_Collection::get_windows_count()const
{
	return windows_info_collection_.size();
}

int	
Windows_Information_Collection::add_windows_information(const Windows_Information * win_info)
{
	IF_NULL_RETURN_VALUE(win_info, -1);
	if (!is_this_already_exist(win_info)) {
		windows_info_collection_.push_back(win_info);
		return 0;
	}
	return -1;
}

Windows_Information_Collection::Windows_Info_Collection::iterator 
Windows_Information_Collection::find_windows_info_referrence(const Windows_Information * win_info) 
{
	IF_NULL_RETURN_VALUE(win_info, windows_info_collection_.end());
	return 
	find(windows_info_collection_.begin(), windows_info_collection_.end(), win_info);
}
int	
Windows_Information_Collection::del_windows_information(const Windows_Information * win_info)
{
	IF_NULL_RETURN_VALUE(win_info, -1);
	Windows_Info_Collection::iterator iter = find_windows_info_referrence(win_info);
	if (windows_info_collection_.end() != iter) {
		delete *iter;
		windows_info_collection_.erase(iter);
		return 0;
	}
	return -1;
}

const Windows_Information * 
Windows_Information_Collection::get_windows_information(size_t win_id) const
{
	if (win_id >= 0 && win_id < windows_info_collection_.size()) {
		return windows_info_collection_[win_id];
	}
	return NULL;
}

const Windows_Information * 
Windows_Information_Collection::get_windows_information(const char * win_root) const
{
	IF_NULL_RETURN_VALUE(win_root, NULL);
	Windows_Info_Collection::const_iterator end = windows_info_collection_.end();
	for (Windows_Info_Collection::const_iterator index = windows_info_collection_.begin();
	end != index; ++ index) {
		if ((*index)->directories_[WINDOWS_DIR] == win_root) {
			return *index;
		}
	}
	return NULL;
}

bool	
Windows_Information_Collection::is_this_already_exist(const Windows_Information * win_info) const
{
	IF_NULL_RETURN_VALUE(win_info, false);
	if (get_windows_information(win_info->get_directorie(WINDOWS_DIR))) return true;
	return false;
}
